/*
 *  particlebody.cpp
 *  EPPI-0.0
 *
 *  Created by Juan Carlos Garcia Orden on 13/07/2010
 *
 */

#include "particlebody.h"

ParticleBody::ParticleBody(ifstream &in, string cname, MecSystem *pSys)
:	Body(in,cname,pSys)
{	
	dim = parentSystem->dim;	/** Must be set always.  dim belongs to the mother class Body */
	type = "particlebody";
	
	char keyword[20];
	string auxs;
	vector<string> auxsv(1);		/** Aux string vector */

	while (in >> keyword && strcmp(keyword,"ENDBODY") )
	{
		// keyword has the POINT label
		in >> auxs;	// Reads the name of the point
		if(checkForSlash(auxs)==false)	addSystemName(auxs,parentSystem->name);
		auxsv[0] = auxs;
		in >> auxs;	// keyword has the MASS label
		in >> mass;
		vComponents.push_back(new Particle(mass,auxsv,dim));				
	}

	vPointNamesSurface.push_back(auxsv[0]);
	
	contactAllOption = true;
	vPointNamesContact = vPointNamesSurface;
	
	if(parentSystem->getProcNum()==0) cout << "	Body " << name << " succesfully read \n";

}

// ***

void ParticleBody::setPTPointsComp()
{
	int j, k;
	vector<string> auxs;
	map<string, Point*, less<string> > maux;
	pair<string,Point*> mauxEntry;
	pair<string,int> sharedEntry;
	
	for(j=0; j<vComponents.size(); j++)		
	//Loop on the components
	{
		auxs = (vComponents[j]->getPointNames());
		for(k=0; k<auxs.size(); k++)		
		// Loop on the names of the points within each component
		{
			/** If the point it is not at the local process ... */
			if( (parentSystem->checkIfPointProcess(auxs[k]))==false )
			{
				/** ...  create it at root system, copying the original point from the remote process */
				parentSystem->createPointAtRoot( parentSystem->getPTPoint(auxs[k]) );
				/** ...  and add the name of the shared point at the remote process */
				parentSystem->addRemoteSharedPoint(auxs[k],parentSystem->getProcNum());
			}
			mauxEntry.first = auxs[k];
			mauxEntry.second = (parentSystem->getPTPointLocal(auxs[k]));
			maux.insert(mauxEntry);
		}
		vComponents[j]->setMPoints(maux);
		maux.clear();
	}
}

// ***

void ParticleBody::setPTPointsLoad()
{
	int j, k;
	vector<string> auxs;
	map<string, Point*, less<string> > maux;
	pair<string,Point*> mauxEntry;
	pair<string,int> sharedEntry;
	
	for(j=0; j<vLoads.size(); j++)		
	//Loop on the Loads
	{
		auxs = (vLoads[j]->getPointNames());
		for(k=0; k<auxs.size(); k++)		
		// Loop on the names of the points within each component
		{
			/** If the point it is not at the local process ... */
			if( (parentSystem->checkIfPointProcess(auxs[k]))==false )
			{
				/** ...  create it at root system, copying the original point from the remote process */
				parentSystem->createPointAtRoot( parentSystem->getPTPoint(auxs[k]) );
				/** ...  and add the name of the shared point at the remote process */
				parentSystem->addRemoteSharedPoint(auxs[k],parentSystem->getProcNum());
			}
			mauxEntry.first = auxs[k];
			mauxEntry.second = (parentSystem->getPTPointLocal(auxs[k]));
			maux.insert(mauxEntry);
		}
		vLoads[j]->setMPoints(maux);
		maux.clear();
	}

}

// ***

void ParticleBody::setPPointSurface()
{
	
	vPPointSurface.resize(1);
	
//	cout << "KKKKK = " << vPointNamesSurface[0] << endl;
	
	vPPointSurface[0] = parentSystem->getPTPointLocal( vPointNamesSurface[0] ); 
//	cout << "KKKKKKKKKK = " << vPPointSurface[0]->name << endl;	
	
/*
	// Build the vector of pointers to the surface points
	vPPointSurface.resize(vPointNamesSurface.size());
	
	int i;
	string auxs;
	for(i=0;i<vPointNamesSurface.size();i++)
	{
		auxs = vPointNamesSurface[i];
		if(checkForSlash(auxs)==false)	addSystemName(auxs,parentSystem->name);
		vPPointSurface[i] = parentSystem->getPTPointLocal( auxs ); 
	}	
*/
}

// ***

void ParticleBody::setMatAtComp()
{}

// ***

void ParticleBody::getBoundary(vector<vector<string> >& connect)
{
	// Already set in the constructor
}

// ***

void ParticleBody::writeMSH(ofstream &fGraph)
{}

// ***

void ParticleBody::writeVTU(ofstream &fGraph, bool& plotDispFlag, bool& plotProcFlag, bool& plotStressFlag)
{

	int i;
	int j;
	int nt;
	double sside = 0.1;	// Semiside of the cube
	int npoints;		// Points of the cell

	nt = vPPointSurface[0]->globalTNum.size();	// Number of translational dofs
	vector<double> aux(nt);

	for (j=0; j<nt; ++j)
	{
		aux[j] = parentSystem->getDof( vPPointSurface[0]->globalTNum[j] ) ;		// coords of the particle
	}
	
	localFGraph << "<?xml version=\"1.0\"?>\n";
	localFGraph << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
	localFGraph << "	<UnstructuredGrid>\n";
//	localFGraph << "		<Piece NumberOfPoints=\"" << 8 << "\" NumberOfCells=\"" << 1 << "\">\n";
	localFGraph << "		<Piece NumberOfPoints=\"" << 1 << "\" NumberOfCells=\"" << 1 << "\">\n";
	localFGraph << "			<Points>\n";
	localFGraph << "				<DataArray type=\"Float64\" NumberOfComponents=\"3\" format=\"ascii\">";
	localFGraph << "\n";
	localFGraph << "				";
		
	localFGraph <<  aux[0] << "\t"; 
	if (nt>1)	localFGraph <<  aux[1] << "\t"; else localFGraph << 0.0;
	if (nt>2)	localFGraph <<  aux[2] << "\t"; else localFGraph << 0.0;	

	/*
	// First point
	localFGraph <<  aux[0] + sside << "\t"; 
	if (nt>1)	localFGraph <<  aux[1] + sside << "\t"; else localFGraph << sside;
	if (nt>2)	localFGraph <<  aux[2] + sside << "\t"; else localFGraph << sside;
	// Second point
	localFGraph <<  aux[0] - sside << "\t"; 
	if (nt>1)	localFGraph <<  aux[1] + sside << "\t"; else localFGraph << sside;
	if (nt>2)	localFGraph <<  aux[2] + sside << "\t"; else localFGraph << sside;
	// Third point
	localFGraph <<  aux[0] - sside << "\t"; 
	if (nt>1)	localFGraph <<  aux[1] - sside << "\t"; else localFGraph << -sside;
	if (nt>2)	localFGraph <<  aux[2] + sside << "\t"; else localFGraph << sside;
	// Fourth point
	localFGraph <<  aux[0] + sside << "\t"; 
	if (nt>1)	localFGraph <<  aux[1] - sside << "\t"; else localFGraph << -sside;
	if (nt>2)	localFGraph <<  aux[2] + sside << "\t"; else localFGraph << sside;
	
	// Fifth point
	localFGraph <<  aux[0] + sside << "\t"; 
	if (nt>1)	localFGraph <<  aux[1] + sside << "\t"; else localFGraph << sside;
	if (nt>2)	localFGraph <<  aux[2] - sside << "\t"; else localFGraph << -sside;
	// Sixth point
	localFGraph <<  aux[0] - sside << "\t"; 
	if (nt>1)	localFGraph <<  aux[1] + sside << "\t"; else localFGraph << sside;
	if (nt>2)	localFGraph <<  aux[2] - sside << "\t"; else localFGraph << -sside;
	// Seventh point
	localFGraph <<  aux[0] - sside << "\t"; 
	if (nt>1)	localFGraph <<  aux[1] - sside << "\t"; else localFGraph << -sside;
	if (nt>2)	localFGraph <<  aux[2] - sside << "\t"; else localFGraph << -sside;
	// Eighth point
	localFGraph <<  aux[0] + sside << "\t"; 
	if (nt>1)	localFGraph <<  aux[1] - sside << "\t"; else localFGraph << -sside;
	if (nt>2)	localFGraph <<  aux[2] - sside << "\t"; else localFGraph << -sside;
	*/

	localFGraph << "\n";
	localFGraph << "				</DataArray>\n";
	localFGraph << "			</Points>\n";
	localFGraph<< "			<Cells>\n";
	localFGraph << "				<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">";
	
	localFGraph << 0 ;
	//localFGraph << 0 << "\t" << 1 << "\t" << 2 << "\t" << 3 << "\t" << 4 << "\t" << 5 << "\t" << 6 << "\t" << 7;
	
	localFGraph << "\n";
	localFGraph << "					";
	
	localFGraph << "\n";
	localFGraph << "				</DataArray>\n";
	localFGraph << "				<DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">";
	localFGraph << "\n";
	localFGraph << "					";
	
	localFGraph << 1 ;
	
	localFGraph << "\n";
	localFGraph << "				</DataArray>\n";
	localFGraph << "				<DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">";
	localFGraph << "\n";
	localFGraph << "					";
	
	localFGraph << 1;
	
	localFGraph << "\n";
	localFGraph << "				</DataArray>\n";
	localFGraph<< "			</Cells>\n";
	
	localFGraph << "		</Piece>\n";
	
	localFGraph << "	</UnstructuredGrid>\n";
	localFGraph << "</VTKFile>\n";	
}

// ***

void ParticleBody::writeOOGL(ofstream &fGraph)
{}

// ***

void ParticleBody::writeFileTemp(const double& time, ofstream & outF)
{}

// ***

void ParticleBody::setIniPosBody(vector<double>& iniValues)
{}